package master;
import java.awt.*;

import javax.swing.JFrame;
import javax.swing.JPanel;

import master.*;

public class Qubit extends ComplexNumber{
	final QuantumRegister myReg;
	final int myBit;
	public Qubit(QuantumRegister myReg, int myBit){
		super(0,0);
		if(myBit >= myReg.getQBitLength()||myBit <0)
			throw new IllegalArgumentException("Invalid Qubit");
		
		this.myReg = myReg;
		this.myBit = myBit;
	}
	public float getReal(){
		return getMagnitudes().getReal();
	}
	public float getImaginary(){
		return getMagnitudes().getImaginary();
	}
	public ComplexNumber getMagnitudes(){
		float oneMag = 0, zeroMag = 0;
		//real part corresponds to states with qubit = 1
		//imaginary corresponds to states with qubit = 0
		for(int i = 0 ; i < myReg.getDimension();i++){
			String bitString = myReg.bitString(i);
			if(bitString.charAt(myBit) == '1')
				oneMag += myReg.magSquared(i).getReal();
			else if(bitString.charAt(myBit) == '0')
				zeroMag += myReg.magSquared(i).getReal();
		}
		//System.out.println(Math.sqrt(oneMag)+Math.sqrt(zeroMag));
		return new ComplexNumber((float)Math.sqrt(oneMag),(float)Math.sqrt(zeroMag));
		
	}
	public void draw(Graphics g, int x , int y , float scale){
		super.draw(g, x, y, scale);
		float one = this.getReal()/this.getMagnitudes().magnitude().getReal();
		float zero = this.getImaginary()/this.getMagnitudes().magnitude().getReal();
		float textSize = 10;
		((Graphics2D)g).scale(textSize , textSize );
		g.setColor(new Color(0,0,255,(int)(255*one)));
		g.drawString("1", (int)(x/textSize- textSize/3), (int)(y/textSize + textSize/3));
		g.setColor(new Color(255,0,0,(int)(255*zero)));
		g.drawString("0", (int)(x/textSize- textSize/3), (int)(y/textSize+ textSize/3));
		((Graphics2D)g).scale(1/textSize , 1/textSize );
	}
	public float getBlochTheta(){
		return (float)(
				Math.abs(this.getReal())/(this.getReal()+this.getImaginary()) *Math.PI
				);
	}
	public float getBlochPhi(){
		//find the total difference in phase between the two states
		
		return (float) (Math.PI/3);
	}
	public static void display(String title,boolean horizontal , boolean editable, ComplexNumber ... numbers){
		JFrame myFrame = new JFrame();
		myFrame.setTitle(title);
		int defaultDimension = 200;
		if(horizontal){
			myFrame.setLayout(new GridLayout(1,numbers.length));
			myFrame.setSize(defaultDimension*numbers.length,defaultDimension);
		}
		else{
			myFrame.setLayout(new GridLayout(numbers.length,1));
			myFrame.setSize(defaultDimension,defaultDimension*numbers.length);
		}
		for(int i = 0 ; i < numbers.length ; i++){
			myFrame.getContentPane().add(
					new ComplexNumberPanel(myFrame,numbers[i],75f,editable)
			);
		}
		
		myFrame.setVisible(true);
	}
	public static JPanel display(int defaultDimension,boolean horizontal , boolean editable, Qubit ... numbers){
		return display(100f, defaultDimension,  horizontal ,editable, numbers);
	}
	public static JPanel display(float scale,int defaultDimension,boolean horizontal , boolean editable, Qubit ... numbers){
		JPanel mainPanel = new JPanel();
		if(horizontal){
			mainPanel.setLayout(new GridLayout(1,numbers.length));
			mainPanel.setSize(defaultDimension*numbers.length,defaultDimension);
		}
		else{
			mainPanel.setLayout(new GridLayout(numbers.length,1));
			mainPanel.setPreferredSize(new Dimension(defaultDimension,defaultDimension*numbers.length));
		}
		for(int i = 0 ; i < numbers.length ; i++){
			mainPanel.add(
					new QubitPanel(mainPanel,numbers[i],scale,editable)
			);
		}
		
		return mainPanel;
	}
	public void measure(){
		myReg.measureQBit(myBit);
	}
}
